//
//  MKAppleLoginUtils.m
//  Fanmugua
//
//  Created by xiaomk on 2020/7/24.
//  Copyright © 2020 taolang. All rights reserved.
//

#import "MKAppleLoginUtils.h"
#import <AuthenticationServices/AuthenticationServices.h>

@interface MKAppleLoginUtils ()<ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding>
@property (nonatomic,strong) UIView *superView;
@property (nonatomic, copy) MKAppleLoginSuccessBlock successBlock;
@property (nonatomic, copy) MKAppleLoginFailedBlock failureBlock;
@end

@implementation MKAppleLoginUtils

MK_IMPL_SHAREDINSTANCE(MKAppleLoginUtils)

#pragma mark - ***** check apple login provider state ******
- (void)checkLoginAuthWithAppleUserId:(NSString *)appleUserId block:(MKBoolBlock)block API_AVAILABLE(ios(13.0)){
    if (appleUserId) {
        ASAuthorizationAppleIDProvider *provider = [[ASAuthorizationAppleIDProvider alloc] init];
        [provider getCredentialStateForUserID:appleUserId completion:^(ASAuthorizationAppleIDProviderCredentialState credentialState, NSError * _Nullable error) {
            switch (credentialState) {
                case ASAuthorizationAppleIDProviderCredentialAuthorized:
                    MK_BLOCK_EXEC(block, YES);
                    break;
                case ASAuthorizationAppleIDProviderCredentialRevoked:
                    // Apple ID Credential revoked, handle unlink
                    MK_BLOCK_EXEC(block, NO);
                    break;
                case ASAuthorizationAppleIDProviderCredentialNotFound:
                    //找不到凭证
                    MK_BLOCK_EXEC(block, NO);
                    break;
                default:
                    break;
            }
        }];
    }
}

#pragma mark - ***** apple login ******
- (void)authWithSuperView:(UIView *)superView success:(MKAppleLoginSuccessBlock)success failure:(MKAppleLoginFailedBlock)failure API_AVAILABLE(ios(13.0)){
    self.successBlock = success;
    self.failureBlock = failure;
    self.superView = superView;
    
    ASAuthorizationAppleIDProvider *appleIDProvider = [[ASAuthorizationAppleIDProvider alloc] init];
    ASAuthorizationAppleIDRequest *request = [appleIDProvider createRequest];
    request.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];
    ASAuthorizationController *authCtrl = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]];
    authCtrl.delegate = self;
    authCtrl.presentationContextProvider = self;
    [authCtrl performRequests];
    
}

#pragma mark - ***** ASAuthorizationControllerDelegate ******
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0)){
    NSLog(@"授权完成:::%@", authorization.credential);
    NSLog(@"controller : %@", controller);
    NSLog(@"authorization : %@", authorization);
    if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
        
        ASAuthorizationAppleIDCredential *credential = (ASAuthorizationAppleIDCredential *)authorization.credential;
        NSString *state = credential.state;
        NSString *userID = credential.user;
        NSPersonNameComponents *fullName = credential.fullName;
        NSString *email = credential.email;
        // refresh token
        NSString *authorizationCode = [[NSString alloc] initWithData:credential.authorizationCode encoding:NSUTF8StringEncoding];
        // access token
        NSString *identityToken = [[NSString alloc] initWithData:credential.identityToken encoding:NSUTF8StringEncoding];
        ASUserDetectionStatus realUserStatus = credential.realUserStatus;
        
        NSLog(@"state: %@", state);
        NSLog(@"userID: %@", userID);
        NSLog(@"fullName: %@", fullName);
        NSLog(@"email: %@", email);
        NSLog(@"authorizationCode: %@", authorizationCode);
        NSLog(@"identityToken: %@     长度:%ld", identityToken,(long)identityToken.length);
        NSLog(@"realUserStatus: %@", @(realUserStatus));
//        [self serverVerifyWithUserId:userID authCode:authorizationCode token:identityToken];
//        return;
        MKAppleLoginModel *model = [[MKAppleLoginModel alloc] init];
        model.userID = userID;
        model.email = email;
        model.authCode = authorizationCode;
        model.identityToken = identityToken;
        if (fullName){
            model.fullName = [NSString stringWithFormat:@"%@%@%@",fullName.familyName?:@"",fullName.middleName?:@"",fullName.givenName?:@""];
        }
        MK_BLOCK_EXEC(self.successBlock, model);
    }else if ([authorization.credential isKindOfClass:[ASPasswordCredential class]]){
        // Sign in using an existing iCloud Keychain credential.
        ASPasswordCredential *pass = (ASPasswordCredential *)authorization.credential;
        MKAppleLoginModel *model = [[MKAppleLoginModel alloc] init];
        model.userName = pass.user;
        model.password = pass.password;
        NSLog(@"userName : %@, password : %@",model.userName, model.password);
        MK_BLOCK_EXEC(self.successBlock, model);
    }else{
        MK_BLOCK_EXEC(self.failureBlock, -1, @"认证类型异常");
    }
}

- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0)){
    NSLog(@"Handle error：%@", error);
    NSString *errorMsg = @"取消授权";
    switch (error.code) {
        case ASAuthorizationErrorCanceled:
            errorMsg = @"取消了授权请求";
            break;
        case ASAuthorizationErrorFailed:
            errorMsg = @"授权请求失败";
            break;
        case ASAuthorizationErrorInvalidResponse:
            errorMsg = @"授权请求响应无效";
            break;
        case ASAuthorizationErrorNotHandled:
            errorMsg = @"未能处理授权请求";
            break;
        case ASAuthorizationErrorUnknown:
            errorMsg = @"授权请求失败未知原因";
            break;
        default:
            break;
    }
    MK_BLOCK_EXEC(self.failureBlock, error.code, errorMsg);
}

#pragma mark - ***** ASAuthorizationControllerPresentationContextProviding ******
- (ASPresentationAnchor)presentationAnchorForAuthorizationController:(ASAuthorizationController *)controller API_AVAILABLE(ios(13.0)){
    if (self.superView) {
        return self.superView.window;
    }
    return [self getCurrentWindow];
}
- (UIWindow *)getCurrentWindow{
    return [self getCurrentWindowByLevel:UIWindowLevelNormal];
}

- (UIWindow *)getCurrentWindowByLevel:(CGFloat)windowLevel{
    UIWindow *topWindow = [[UIApplication sharedApplication] keyWindow];
    if (topWindow.windowLevel != windowLevel) {
        NSArray *windows = [[UIApplication sharedApplication] windows];
        for (UIWindow *window in windows) {
            if (window.windowLevel == windowLevel) {
                topWindow = window;
            }
        }
    }
    return topWindow;
}
#pragma mark - ***** server ******
/**
 * https://appleid.apple.com/auth/token
 * client_id : BundleID
 * code : authorizationCode
 * grant_type : @"authorization_code"  固定值
 * client_secret ：需要服务器自行计算
 * client_secret的计算方法：
    其实是一个jwt的构建方法，下面列出一段Ruby的生成方法，让服务器按照参数自行生成一下即可：
     require "jwt"
     key_file = "xxxxx.p8" #从Developer Center后台下载的那个p8文件
     team_id = "xxxxxx"             #开发者账号的teamID
     client_id = "com.xxx.xxx" #应用的BundleID
     key_id = "xxxxxx"               #从Developer Center后台找到keyid
     validity_period = 180 #有效期 180天  测试的时候用 后端写的时候 让后端自己控制生成

     private_key = OpenSSL::PKey::EC.new IO.read key_file

     token = JWT.encode(
         {
             iss: team_id,
             iat: Time.now.to_i,
             exp: Time.now.to_i + 86400 * validity_period,
             aud: "https://appleid.apple.com",
             sub: client_id
         },
         private_key,
         "ES256",
         header_fields=
         {
             kid: key_id
         }
     )
     puts token
 *
 */

//- (void)serverVerifyWithUserId:(NSString *)uid authCode:(NSString *)authCode token:(NSString *)token{
//    NSDictionary *jwtDic = [self jwtDecodeWithToken:token];
//    
//    if (jwtDic) {
//        ELog(@"jwtDic : %@",jwtDic);
//        NSDictionary *dict = @{
//            @"client_id" : [MKDeviceUtils appBundleIdentifier],
//            @"grant_type" : @"authorization_code",
//            @"code" : authCode,
//            @"client_secret" : "",
//        };
//        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//        manager.requestSerializer = [AFHTTPRequestSerializer serializer];
////      manager.responseSerializer = [AFHTTPResponseSerializer serializer];
////      manager.requestSerializer = [AFJSONRequestSerializer serializer];
//        manager.requestSerializer.timeoutInterval = 30.f;
//        [manager.requestSerializer setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
//        manager.responseSerializer = [AFJSONResponseSerializer serializer];
//        manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/html",@"text/plain", nil];
//        
////        NSDictionary *header = @{
////            @"Content-Type" : @"application/x-www-form-urlencoded"
////        };
//        [manager POST:@"https://appleid.apple.com/auth/token" parameters:dict headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
//            ELog(@"--success-->%@",responseObject);
//            NSDictionary *dict2 = [self jwtDecodeWithToken:[responseObject objectForKey:@"id_token"]];
//            ELog(@">>解析请求到的:%@",dict2);
//        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//            ELog(@"--error-->%@",error.localizedDescription);
//        }];
//    }
//}

- (NSDictionary *)jwtDecodeWithToken:(NSString *)jwtStr {
    NSArray *segments = [jwtStr componentsSeparatedByString:@"."];
    if (segments.count >= 2) {
        NSString *base64String = [segments objectAtIndex:1];
        int requiredLength = (int)(4 *ceil((float)[base64String length]/4.0));
        int nbrPaddings = requiredLength - (int)[base64String length];
        if(nbrPaddings > 0){
            NSString *pading = [[NSString string] stringByPaddingToLength:nbrPaddings withString:@"=" startingAtIndex:0];
            base64String = [base64String stringByAppendingString:pading];
        }
        base64String = [base64String stringByReplacingOccurrencesOfString:@"-" withString:@"+"];
        base64String = [base64String stringByReplacingOccurrencesOfString:@"_" withString:@"/"];
        NSData *decodeData = [[NSData alloc] initWithBase64EncodedString:base64String options:0];
        NSString *decodeString = [[NSString alloc] initWithData:decodeData encoding:NSUTF8StringEncoding];
        NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:[decodeString dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
        return jsonDict;
    }
    return nil;
}
@end




@implementation MKAppleLoginModel
@end
